#include <types.h>
#include <memory.h>
#include <kalloc.h>
#include <stdio.h>


// The last PDE is aliased to the page directory itself. This enables us to
// modify page PTs even though we don't know where in VM are they. PGs should
// be alligned to a page boundary.
static uint32_t kern_pgdir[PG_NUM] __attribute__ ((aligned(PG_SIZE))) = {
	[PG_NUM - 1] = KERN_V2P((uint32_t)kern_pgdir)
};

static void virt_map(uint32_t *pgdir, uint32_t va, uint32_t pa, uint32_t size, uint32_t perm);
static uint32_t virt_find_pte(uint32_t *pgdir, uint32_t va);


void
kvm_init()
{
	ph_alloc_init();
	
	printf("kern_end %x\n",kern_end);
	printf("kern_pgidr %x\n",kern_pgdir);
	
	virt_map(kern_pgdir, KERNBASE, 0, KERN_V2P((uint32_t)kern_end), PG_PRESENT);
}

static void
virt_map(uint32_t *pgdir, uint32_t va, uint32_t pa, uint32_t size, uint32_t perm)
{
	uint32_t va_end = va + size;
	
	va = PG_ROUND_DOWN(va);
	pa = PG_ROUND_DOWN(pa);
	
	for( ; va <= va_end; va += PG_SIZE, pa += PG_SIZE )
	{
		virt_find_pte(pgdir, va);
	}
	
}

static uint32_t
virt_find_pte(uint32_t *pgdir, uint32_t va)
{
	//uint32_t pte; // Page table entry that contains va.
	uint32_t pde = pgdir[LIN2PDE(va)]; // Page directory entry that contains va.
	
	// If the PDE is not present allocate a page of physical memory for it..
	if( !(pde & PG_PRESENT) )
	{
		pde = ph_alloc() | PG_PRESENT;
	}
	
	//pte
	
	return 0;
}